package com.jp.knowledge.activity;

import android.content.Intent;
import android.os.Handler;
import android.support.design.widget.TabLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.bigkoo.quicksidebar.QuickSideBarTipsView;
import com.bigkoo.quicksidebar.QuickSideBarView;
import com.bigkoo.quicksidebar.listener.OnQuickSideBarTouchListener;
import com.google.gson.JsonObject;
import com.jiayen.cache.FileCacheManager;
import com.jiayen.util.ToasUtil;
import com.jp.knowledge.R;
import com.jp.knowledge.adapter.team_circle.TeamCircleConstactsAdapter;
import com.jp.knowledge.adapter.team_circle.TeamCircleConstactsSelectedAdapter;
import com.jp.knowledge.comm.SlidingActivity;
import com.jp.knowledge.http.HttpHelper;
import com.jp.knowledge.model.IModel;
import com.jp.knowledge.model.TeamCircleConstactsModel;
import com.jp.knowledge.model.UserData;
import com.jp.knowledge.my.base.RecycleVAdapter;
import com.jp.knowledge.my.model.OrganizaModel;
import com.jp.knowledge.my.util.MyUtil;
import com.jp.knowledge.my.util.PinyinComparator;
import com.jp.knowledge.util.ResultSubscriber;
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;

import org.xutils.view.annotation.ViewInject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import pl.droidsonroids.gif.GifImageView;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class TeamCircleConstactsActivity extends SlidingActivity implements ResultSubscriber.OnResultListener, View.OnClickListener, TeamCircleConstactsAdapter.OnItemSelectedListener, RecycleVAdapter.OnItemClickListener {

    protected static final int GET_CONSTACTS_CODE = 0x01;
    public static final String TITLE = "title";
    public static final String COMPANY_ID = "companyId";
    public static final String COMPANY_TYPE = "companyType";
    public static final String SELECT_CONSTACTS_DATA = "selectConstactsData";

    @ViewInject(R.id.team_circle_contacts_edit_search)
    protected EditText constactEdit;
    @ViewInject(R.id.team_circle_contacts_iv_clear)
    private ImageView constactEditClear;
    @ViewInject(R.id.team_circle_contacts_rv)
    protected RecyclerView constactsListRv;
    @ViewInject(R.id.team_circle_contacts_sbv)
    private QuickSideBarView sideBarSbv;
    @ViewInject(R.id.team_circle_contacts_btv)
    private QuickSideBarTipsView sideBarBtv;
    @ViewInject(R.id.team_circle_contacts_selected_rv)
    private RecyclerView constactsSelectedRv;
    @ViewInject(R.id.team_circle_contacts_selected_bn)
    private TextView constactsSelectedBn;
    @ViewInject(R.id.loading_bg)
    private GifImageView loadingView;

    private List<TeamCircleConstactsModel> allConstactsData;
    private List<TeamCircleConstactsModel> constactsListData;
    private List<TeamCircleConstactsModel> selectConstacts;

    protected TeamCircleConstactsAdapter constactsAdapter;
    private TeamCircleConstactsSelectedAdapter selectedAdapter;
    private LinearLayoutManager constactsListLayoutManager;
    protected List<String> letters;

    private Intent intent;
    private String companyId;
    private int companyType;
    private String cachePath;
    private FileCacheManager cacheManager;

    @Override
    protected int getResourceId() {
        return R.layout.team_circle_contacts;
    }

    @Override
    protected void init() {
        initData();
        initTitle();
        initOther();
        readCache();
    }

    private void initData(){
        intent = getIntent();
        companyId = intent.getStringExtra(COMPANY_ID);
        companyType = intent.getIntExtra(COMPANY_TYPE, 0);
        selectConstacts = (List)intent.getSerializableExtra(SELECT_CONSTACTS_DATA);
        if(selectConstacts == null)
            selectConstacts = new ArrayList<>();
        allConstactsData = new ArrayList<>();
        constactsListData = new ArrayList<>();
        cachePath = getCacheDir().getPath() + "/team_circle_constacts_" + companyId + "_" + companyType + ".dat";
        cacheManager = new FileCacheManager();
    }

    private void initTitle(){
        topName.setText(getIntent().getStringExtra(TITLE));
        topDesc.setVisibility(View.GONE);
        leftIcon.setImageResource(R.mipmap.arrow_white_left);
        rightIcon.setVisibility(View.GONE);
        leftIcon.setOnClickListener(this);
    }

    private void initOther(){
        constactsAdapter = new TeamCircleConstactsAdapter(this, constactsListData);
        selectedAdapter = new TeamCircleConstactsSelectedAdapter(this, selectConstacts);
        constactsAdapter.setOnItemSelectedListener(this);

        constactsListRv.setHasFixedSize(true);
        constactsListLayoutManager = new LinearLayoutManager(this);
        constactsListRv.setLayoutManager(constactsListLayoutManager);
        StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(constactsAdapter);
        constactsListRv.addItemDecoration(headersDecor);
        constactsListRv.setAdapter(constactsAdapter);
        constactsListRv.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                MyUtil.closeKeyword(TeamCircleConstactsActivity.this, constactEdit);
                if (movePosition < 0)
                    return;
                int n = movePosition - constactsListLayoutManager.findFirstVisibleItemPosition();
                if (0 <= n && n < constactsListRv.getChildCount()){
                    int top = constactsListRv.getChildAt(n).getTop();
                    constactsListRv.scrollBy(0, top);
                }
                movePosition = -1;
            }
        });
        constactEdit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    MyUtil.closeKeyword(TeamCircleConstactsActivity.this, constactEdit);
                }
                return true;
            }
        });

        constactsSelectedRv.setHasFixedSize(true);
        constactsSelectedRv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        constactsSelectedRv.setAdapter(selectedAdapter);
        selectedAdapter.addItemClickListener(this);

        letters = Arrays.asList(getResources().getStringArray(R.array.constacts_letters));
        sideBarSbv.setLetters(letters);
        sideBarSbv.setOnQuickSideBarTouchListener(new OnQuickSideBarTouchListener() {
            @Override
            public void onLetterChanged(String letter, int position, float y) {
                sideBarBtv.setText(letter, position, (sideBarSbv.getY() - sideBarBtv.getY()) + y - sideBarBtv.getWidth());
                letterChanged(letter, position, y);
            }
            @Override
            public void onLetterTouching(boolean touching) {
                sideBarBtv.setVisibility(touching ? View.VISIBLE : View.INVISIBLE);
            }
        });

        constactEditClear.setOnClickListener(this);
        constactEditClear.setVisibility(View.GONE);
        constactEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}
            @Override
            public void afterTextChanged(Editable s) {
                if(s.length() == 0 && constactEditClear.getVisibility() != View.GONE)
                    constactEditClear.setVisibility(View.GONE);
                else if(s.length() != 0 && constactEditClear.getVisibility() != View.VISIBLE)
                    constactEditClear.setVisibility(View.VISIBLE);
                editTextChange();
            }
        });

        constactsSelectedBn.setOnClickListener(this);
        setSelectBtn();
    }

    private void letterChanged(String letter, int position, float y){
        for(int i = 0; i < constactsListData.size(); i++){
            if(constactsListData.get(i).getRemark().charAt(0) == letters.get(position).charAt(0)){
                moveToPosition(i);
                return;
            }
        }
    }

    private void editTextChange(){
        String searchStr = constactEdit.getText().toString();
        constactsListData.clear();
        if(searchStr.length() == 0){
            constactsListData.addAll(allConstactsData);
        } else{
            for(TeamCircleConstactsModel constactsModel : allConstactsData){
                if(constactsModel.getUserName() != null && constactsModel.getUserName().contains(searchStr))
                    constactsListData.add(constactsModel);
            }
        }
        constactsAdapter.updateAdapter(constactsListData);
    }

    private int movePosition = -1;
    private void moveToPosition(int position) {
        int firstItem = constactsListLayoutManager.findFirstVisibleItemPosition();
        int lastItem = constactsListLayoutManager.findLastVisibleItemPosition();
        if (position <= firstItem){
            constactsListRv.scrollToPosition(position);
        }else if (position <= lastItem){
            int top = constactsListRv.getChildAt(position - firstItem).getTop();
            constactsListRv.scrollBy(0, top);
        }else{
            constactsListRv.scrollToPosition(position);
            movePosition = position;
        }
    }

    private void getData(){
        if(constactsAdapter.getItemCount() == 0)
            loadingView.setVisibility(View.VISIBLE);
        JsonObject param = new JsonObject();
        param.addProperty("token", HttpHelper.token);
        if(companyType == 2){       // 学校使用classId
            List<OrganizaModel> companyList = application.getUserData().getCompanyList();
            for(OrganizaModel organizaModel : companyList){
                if(organizaModel.getCompanyId().equals(companyId)){
                    param.addProperty("companyId", organizaModel.getClassId());
                    break;
                }
            }
        } else {
            param.addProperty("companyId", companyId);
        }
        param.addProperty("companyType", companyType);
        HttpHelper.getInstance(this).teamCircleConstacts(param, GET_CONSTACTS_CODE, this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.icon_left:
                finishSelf();
                break;
            case R.id.team_circle_contacts_iv_clear:
                constactEdit.setText("");
                break;
            case R.id.team_circle_contacts_selected_bn:
                intent.putExtra(SELECT_CONSTACTS_DATA, (Serializable)selectConstacts);
                setResult(RESULT_OK, intent);
                finishSelf();
                break;
        }
    }

    @Override
    public void onItemSelect(int position, boolean isChecked) {
        if(position < 0 || position >= constactsListData.size())
            return;
        constactsListData.get(position).setIsChecked(isChecked);
        if(isChecked)
            selectConstacts.add(constactsListData.get(position));
        else
            selectConstacts.remove(constactsListData.get(position));
        selectedAdapter.updateAdapter(selectConstacts);
        setSelectBtn();
    }
    @Override
    public void itemSelect(int position) {
        if(position < 0 || position >= selectConstacts.size())
            return;
        TeamCircleConstactsModel data = selectConstacts.remove(position);
        data.setIsChecked(false);

        int constactIndex = constactsListData.indexOf(data);
        if(constactIndex > 0 && constactIndex < constactsListData.size())
            constactsAdapter.notifyItemChanged(constactIndex);

        selectedAdapter.notifyItemRemoved(position);
        setSelectBtn();
    }

    @Override
    public void onStart(int requestType) {}
    @Override
    public void onCompleted(int requestType) {
        loadingView.setVisibility(View.GONE);
    }
    @Override
    public void onError(int requestType) {
        onCompleted(requestType);
    }
    @Override
    public void onNext(IModel data, int requestType) {
        if(data.getErrcode() != 0){
            ToasUtil.toast(mContext, data.getMessage());
            onError(requestType);
        } else{
            List<TeamCircleConstactsModel> datas = data.getList(TeamCircleConstactsModel.class);
            setData(datas);
            saveCache(cachePath, allConstactsData);
        }
    }

    private void setData(List<TeamCircleConstactsModel> datas){
        allConstactsData.clear();
        if(datas != null && datas.size() > 0)
            allConstactsData.addAll(datas);
        List<TeamCircleConstactsModel> selfConstactsModels = new ArrayList<>();
        String userId = application.getUserData() == null ? null : application.getUserData().getUuid();
        for(TeamCircleConstactsModel model : allConstactsData){
            if(userId != null && userId.equals(model.getUserId())) {
                selfConstactsModels.add(model);
                continue;
            }
            String userName = model.getUserName();
            if(userName == null)
                userName = "";
            String remark = PinyinComparator.getPinyin(userName).toUpperCase();
            if(remark.length() == 0 || remark.charAt(0) < 'A' || remark.charAt(0) > 'Z')
                remark = '#' + remark;
            model.setRemark(remark);
            model.setIsChecked(selectConstacts.contains(model));
        }
        for(TeamCircleConstactsModel model : selfConstactsModels)
            allConstactsData.remove(model);
        selectConstacts.clear();
        for(TeamCircleConstactsModel model : allConstactsData)
            if(model.getIsChecked())
                selectConstacts.add(model);
        selectedAdapter.updateAdapter(selectConstacts);
        setSelectBtn();
        editTextChange();
    }

    private void setSelectBtn(){
        constactsSelectedBn.setText(String.format(Locale.getDefault(), "确定(%d/%d)",
                selectConstacts.size(), allConstactsData.size()));
    }

    private void finishSelf() {
        MyUtil.closeKeyword(this, constactEdit);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, 300);
    }

    private void readCache(){
        Observable.create(new Observable.OnSubscribe<List<TeamCircleConstactsModel>>() {
            @Override
            public void call(Subscriber<? super List<TeamCircleConstactsModel>> subscriber) {
                List<TeamCircleConstactsModel> datas = (List) cacheManager.readObject(cachePath);
                subscriber.onNext(datas);
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<List<TeamCircleConstactsModel>>() {
            @Override
            public void onCompleted() {
                getData();
            }
            @Override
            public void onError(Throwable e) {
                onCompleted();
            }
            @Override
            public void onNext(List<TeamCircleConstactsModel> data) {
                setData(data);
            }
        });
    }

    private void saveCache(final String cachePath, final Object data){
        new Thread(new Runnable() {
            @Override
            public void run() {
                cacheManager.wirteObject(data, cachePath);
            }
        }).start();
    }
}
